package com.pulaien.shop.controller;

import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Date;

import com.pulaien.system.domain.dto.rakuten.OrdererModel;
import com.pulaien.system.domain.dto.rakuten.RakutenOrderModel;
import com.pulaien.system.domain.dto.rakuten.SenderModel;
import com.pulaien.system.domain.dto.rakuten.SettlementModel;

import javax.xml.bind.annotation.XmlElement;

/**
 * 这是一个自动生成 SQL 语句的类，只需要修改变量 CLS 的参数为对应类（如User.class）<br>
 * 然后执行main方法，就可以得到该类的建表SQL语句，以及对应的插入模拟SQL。
 *
 * @author ZhangYuanqiang
 * @since 2021年4月13日
 */
public class CreateTableSqlUtil {

    // main
    public static void main(String[] a){
        Class klass = SettlementModel.class;
        String outputPath = "输出建表语句/建表语句.txt";   // c:/

        generateTableSql(klass, outputPath, null);

        System.out.println("操作结束");
    }

    // writeFile with BufferedWriter
    public static void writeFile(String content, String outputPath){
        File file = new File(outputPath);
        System.out.println("文件路径: " + file.getAbsolutePath());

        // 输出文件的路径
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }

        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        BufferedWriter out = null;

        try{
            // 如果文件存在，就删除
            if(file.exists()){
                file.delete();
            }

            file.createNewFile();

            fos = new FileOutputStream(file, true);
            osw = new OutputStreamWriter(fos);
            out = new BufferedWriter(osw);

            out.write(content);

            // 清空缓冲流，把缓冲流里的文本数据写入到目标文件里
            out.flush();
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            try{
                fos.close();
            }catch(IOException e){
                e.printStackTrace();
            }

            try{
                osw.close();
            }catch(IOException e){
                e.printStackTrace();
            }

            try{
                out.close();
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }

    public static void generateTableSql(Class obj,
                                        String outputPath, String tableName){
        // tableName 如果是 null，就用类名做表名
        if(tableName == null || tableName.equals("")){
            tableName = obj.getName();
            tableName = tableName.substring(tableName.lastIndexOf(".") + 1);
        }

        // 表名用大写字母
        tableName = tableName.toUpperCase();

        Field[] fields = obj.getDeclaredFields();

        Object param = null;
        String column = null;

        StringBuilder sb = new StringBuilder();

        sb.append("drop table if exists ").append(tableName).append(";\r\n");

        sb.append("\r\n");

        sb.append("create table ").append(tableName).append("(\r\n");

        System.out.println(tableName);

        boolean firstId = true;

        for(int i = 0; i < fields.length; i++){
            Field f = fields[i];

            column = f.getName();

            System.out.println(column + ", " + f.getType().getSimpleName());

            param = f.getType();
            sb.append(column);  // 一般第一个是主键

            if(param instanceof Integer){
                sb.append(" int(10) ");
            }else if(param instanceof Date){
                sb.append(" datetime ");
            }else{
                // 注意：根据需要，自行修改 varchar 的长度。这里设定为长度等于 50
                int length = 50;
                sb.append(" VARCHAR(" + length + ")");
            }
            sb.append(" DEFAULT NULL COMMENT ''");
            if(firstId == true){
                sb.append(" PRIMARY KEY ");
                firstId = false;
            }

            // 获取字段中包含 fieldMeta 的注解

            // 获取属性的所有注释
            Annotation[] allAnnotations = f.getAnnotations();

            XmlElement xmlElement = null;
            Class annotationType = null;

            for(Annotation an : allAnnotations){
                sb.append(" COMMIT '");
                xmlElement =(XmlElement) an;
                annotationType = an.annotationType();
                param =((XmlElement) an).name();
                System.out.println("属性 " + f.getName()
                        + " ----- 的注释类型有: " + param);
                sb.append(param).append("'");
            }

            if(i != fields.length - 1){  // 最后一个属性后面不加逗号
                sb.append(", ");
            }

            sb.append("\n");
        }

        String sql = sb.toString();

        sql = sb.substring(0, sql.length() - 1)
                + "\n) " + "ENGINE = INNODB DEFAULT  CHARSET = utf8;";

        writeFile(sql, outputPath);
    }

}
